﻿#include "ProtoCodeGenerator.h"
#include "XyNetCompiler/ServiceParser.h"

namespace XyNet
{
	using std::endl;

	void ProtoCodeGenerator::generator(ServiceParser* parser)
	{
		filesystem::path protoPath =
			parser->getServiceFilePath().string() + ".message.proto";
		filesystem::ofstream fileStream(protoPath);

		fileStream << R"(syntax = "proto3";)" << endl << endl;

		// 写入import
		auto imports = parser->getImports();
		boost::format importFormat(R"(import "%s";)");
		for (auto iter = imports->begin(); iter != imports->end(); ++iter)
			fileStream << importFormat % *iter << endl;
		if (!imports->empty())
			fileStream << endl;

		// 写入package
		auto package = parser->getPackage();
		if (!package.empty())
			fileStream << boost::format("package %s;") % package << endl << endl;

		// 写入服务
		auto services = parser->getServices();
		for (auto serviceIter = services->begin(); serviceIter != services->end(); ++serviceIter)
		{
			auto service = &*serviceIter;
			fileStream << boost::format("message %sMessage \n{") % service->_name << endl;

			// 写入方法
			for (auto methodIter = service->_methods.begin();
				methodIter != service->_methods.end(); ++methodIter)
			{
				auto method = &*methodIter;
				// 写入请求
				fileStream << boost::format("\tmessage %sRequest \n\t{") % method->_name << endl;
				for (size_t i = 0; i < method->_requestArguments.size(); ++i)
				{
					auto p = &method->_requestArguments[i];
					fileStream << "\t\t";
					fileStream <<
						boost::format("%s %s = %d;") % p->second % p->first % (i + 1) << endl;
				}
				fileStream << "\t}" << endl;

				// 写入应答
				fileStream << boost::format("\tmessage %sResponse \n\t{") % method->_name << endl;
				for (size_t i = 0; i < method->_responseArguments.size(); ++i)
				{
					auto p = &method->_responseArguments[i];
					fileStream << "\t\t";
					fileStream <<
						boost::format("%s %s = %d;") % p->second % p->first % (i + 1) << endl;
				}
				fileStream << "\t}" << endl;
			}

			fileStream << "}" << endl << endl;
		}
	}

}